from flask import Flask, render_template, Response,request
from flask_cors import CORS
import cv2 as cv
import numpy as np
import sys
import math

from ftauto import serveModel 
from dist import calDist

app = Flask(__name__)
app.jinja_env.auto_reload = True
app.config['TEMPLATES_AUTO_RELOAD'] = True
cors = CORS()
cors.init_app(app=app, resources={r"/api/*": {"origins": "*"}})
#顶部摄像头

@app.route("/")
def index():
    return render_template("index.html")

#获得摄像头图像字节流传输
def gen_frames0(ID):
    if int(ID)>0:    #4号定焦摄像头
        camera = cv.VideoCapture(0)        
        camera.set(3,1920) #设置分辨率
        camera.set(4,1080)
        while 1:
            ret1,frame1= camera.read()
            if not ret1:break   
            #targetDist = calDist(frame1)     
            #把获取到的图像格式转换(编码)成流数据，赋值到内存缓存中;
            #主要用于图像数据格式的压缩，方便网络传输
            # marker = serveModel.find_marker(frame1)            
            # if marker == 0: 
                # continue
        #     # continue
        #     print(marker[1][0])    #目标像素宽
        #     inches = serveModel.distance_to_camera(15, marker[1][0])
        
        # #     # draw a bounding box around the image and display it
        # #     # 在图像周围绘制一个边界框并显示它
        #     box = cv.boxPoints(marker)
        #     box = numpy.int0(box)
        #     cv.drawContours(frame1, [box], -1, (0, 255, 0), 2)
        #     cv.putText(frame1, "%.2fcm" % (inches *30.48/ 12),
        #       (frame1.shape[1] - 200, frame1.shape[0] - 20), cv.FONT_HERSHEY_SIMPLEX,
        #   2.0, (0, 255, 0), 3)


            #cv.putText(frame1,"%.2f"%(imgEvaluate(frame1)),(frame1.shape[1] - 300, frame1.shape[0] -50), cv.FONT_HERSHEY_SIMPLEX,
           # 2.0, (0, 255, 0), 3)
            ret1,buffer = cv.imencode('.jpg',frame1)
            #将缓存里的流数据转成字节流
            frame1 = buffer.tobytes()
            #指定字节流类型image/jpeg
            yield  (b'--frame\r\n'
                    b'Content-Type: image/jpeg\r\n\r\n' + frame1 + b'\r\n')
    else:             #3号下潜摄像头
        camera = cv.VideoCapture(2)   
        print("....")     
        while 1:
            ret,frame= camera.read()
            if not ret:break        
            #把获取到的图像格式转换(编码)成流数据，赋值到内存缓存中;
            #主要用于图像数据格式的压缩，方便网络传输
            
            # cv.putText(frame,int(imageVar),(frame.shape[1] - 200, frame.shape[0] - 20), cv.FONT_HERSHEY_SIMPLEX,
            # 2.0, (0, 255, 0), 3)
            ret1,buffer = cv.imencode('.jpg',frame)
            #将缓存里的流数据转成字节流
            frame = buffer.tobytes()
            #指定字节流类型image/jpeg 
            yield  (b'--frame\r\n'
                    b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')


#网页端请求地址响应，注意那个mimetype资源媒体类型
#服务器推送，使用multipart/mixed混合类型的变种--multipart/x-mixed-replace。
#这里，“x-”表示属于实验类型。“replace”表示每一个新数据块都会代替前一个数据块。
#也就是说，新数据不是附加到旧数据之后，而是替代它，boundary为指定边界
@app.route('/video_feed',methods=['POST','GET'])
def video_feed():
    ID= request.args.get('id')
    return Response(gen_frames0(ID),mimetype='multipart/x-mixed-replace; boundary=frame')
    

#测试机械舵机
@app.route("/servo")
def servo123():
    return render_template("servo.html")

#测试舵机移动
@app.route("/api/servoAct",methods=['POST','GET'])
def servoact():    
    fvel = request.form['fvel']
    facc = request.form['facc']
    fid = request.form['id']
    fdis = request.form['fdis']   
    flag = request.form['flag']   
    return serveModel.act(fid,fvel,facc,fdis,flag)

@app.route("/api/servoStop",methods=['POST','GET'])
def servostop():    
    fid = request.form['id']    
    return serveModel.stop(fid)

def imgEvaluate(img):
    width,height = img.shape[:2][::-1]
    img_resize = cv.resize(img,(int(width*1.0),int(height*1.0)),interpolation=cv.INTER_CUBIC)
    img_gray = cv.cvtColor(img_resize,cv.COLOR_RGB2GRAY)
    imageVar = cv.Laplacian(img_gray, cv.CV_64F).var() #图像模糊度  
    return imageVar

def getDist(frame1):
    focal_legth=8
    
def imgDist(frame1):
    mtx = np.array([[2.40364914e+03, 0.00000000e+00, 9.57470815e+02],
                [0.00000000e+00, 2.39630877e+03, 5.59335485e+02],
                [0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
    dist = np.array([[-4.03724657e-01, -1.73243467e+00, -5.25914647e-03, 2.61270024e-03, 9.83021357e+00]])
    FACE_HALF_HIGH = 7.5
    FACE_HALF_WEIGHT = 7.5
    image_point = []
    Camera_intrinsic = {"mtx": mtx, "dist": dist, } 
    HSV_img = cv.cvtColor(frame1, cv.COLOR_BGR2GRAY)

    # cv2.namedWindow('dst', cv2.WINDOW_AUTOSIZE)
    # cv2.imshow('dst', binary)
    dst, binary = cv.threshold(HSV_img, 100, 255, cv.THRESH_BINARY)
    kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (15, 15))
    binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, kernel)  # 开操作

    contours, _ = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    x = 0
    y = 0
    max_w = 0
    max_h = 0
    max = -1
    #print(len(contours))
    for cont in contours:
        distance = 0
        image_point = []
        obj_points = []

        # 外接矩形
        x, y, w, h = cv.boundingRect(cont)
        # 在原图上画出预测的矩形
        area = w * h
        print(area)
        if (area <50592 and area>10000):
            cv.rectangle(frame1, (x, y), (x + w, y + h), (0, 0, 255), 5)
            #print(w, h)

            t = (x, y)
            image_point.append(t)
            t = (x + w, y)
            image_point.append(t)
            t = (x, y + h)
            image_point.append(t)
            t = (x + w, y + h)
            image_point.append(t)
            image_points = np.array((image_point[-4], image_point[-3], image_point[-2], image_point[-1]), dtype=np.float64)

            o = (-FACE_HALF_WEIGHT, -FACE_HALF_HIGH, 0)
            obj_points.append(o)
            o = (FACE_HALF_WEIGHT, -FACE_HALF_HIGH, 0)
            obj_points.append(o)
            o = (-FACE_HALF_WEIGHT, FACE_HALF_HIGH, 0)
            obj_points.append(o)
            o = (FACE_HALF_WEIGHT, FACE_HALF_HIGH, 0)
            obj_points.append(o)
            obj_point = np.array((obj_points[-4], obj_points[-3], obj_points[-2], obj_points[-1]), dtype=np.float64)
            obj_point = obj_point * 2.9 / 3
        
            #_, rvec, tvec = cv.solvePnP(obj_point, image_points, Camera_intrinsic["mtx"], Camera_intrinsic["dist"])
            #print(tvec[0], tvec[1])
            #distance = math.sqrt(tvec[0] ** 2 + tvec[1] ** 2 + tvec[2] ** 2)  # 计算距离
            focal=8
            unit=234
            distance = 8*unit/15
            if distance >= 250 and distance < 300:
                distance += 5
            elif distance >= 300:
                distance += 10
            print(distance)            
            return distance

if __name__=='__main__':
    app.run(host="0.0.0.0",port=8080)
